<script setup>
import { computed, onMounted, watch } from 'vue'

const tableRef = ref(null)

const tableClass = computed(() => {
  return { 'el-table-scrollbar': props.scrollbar }
})

const errors = ref([])
const props = defineProps({
  data: {
    required: true,
    type: Array,
    default: () => []
  },
  tableColumn: {
    required: true,
    type: Array,
    default: () => []
  },
  showStripe: {
    type: Boolean,
    default: true
  },
  showBorder: {
    type: Boolean,
    default: true
  },
  scrollbar: {
    type: Boolean,
    default: true
  },
  isCanEdit: {
    type: Boolean,
    default: true
  },
  mode: {
    type: String,
    default: 'mode1'
  }
})



const validate = () => {
  errors.value = []
  return new Promise((reslove, reject) => {
    const requiredProp = props.tableColumn.filter(item => item.required).map(item => item.prop)
    requiredProp.length === 0 && reslove()

    for (let i = 0; i < props.data.length; i++) {
      const item = props.data[i]

      for (let j = 0; j < requiredProp.length; j++) {
        const requiredField = requiredProp[j]
        // 这个地方会存在争议  关于输入为0的字段是否需要校验
        if (item[requiredField] !== 0 && !item[requiredField]) {
          errors.value.push({ index: i, prop: requiredField })
        }
      }
    }

    if (errors.value.length === 0) {
      reslove()
    } else {
      ElMessage.error('请填写必填项')
      reject()
    }
  })
}

defineExpose({ validate })
</script>

<template>
  <el-table
    ref="tableRef"
    v-bind="$attrs"
    :data="props.data"
    :stripe="$props.showStripe"
    :border="$props.showBorder"
    :scrollbar-always-on="$props.scrollbar"
    :class="tableClass"
    :row-style="{ height: '45px' }"

    :header-cell-style="{ 'text-align': 'center' }"
  >
    <template v-if="$slots.header">
      <slot name="header"></slot>
    </template>

    <el-table-column
      v-for="item in $props.tableColumn"
      :key="item.prop"
      :align="item.align || 'center'"
      :width="item.width"
      :minWidth="item.minWidth"
      :prop="item.prop"
      :column-key="item.key"
      show-overflow-tooltip
    >
      <template #header>
        <span :class="{ required: item.required }">{{ item.label }}</span>
      </template>

      <template #default="scope">
        <template v-if="item.canEdit && $props.isCanEdit">
          <!-- 选择器 -->
          <template v-if="item.mode === 'select' && item.options">
            <el-select
              v-model="scope.row[item.prop]"
              :placeholder="item.label"
              :class="{
                'error-box-shadow': errors.some(
                  sub => sub.index === scope.$index && sub.prop === item.prop
                )
              }"
            >
              <el-option
                v-for="option in item.options"
                :key="option.value"
                :label="option.label"
                :value="option.value"
              />
            </el-select>
          </template>

          <template v-else>
            <el-input
              v-model.trim="scope.row[item.prop]"
              :type="item.type || 'text'"
              :placeholder="item.label"
              :class="{
                'error-box-shadow': errors.some(
                  sub => sub.index === scope.$index && sub.prop === item.prop
                )
              }"
            />
          </template>
        </template>

        <template v-else>
          <span v-if="item.formatter" v-html="item.formatter(scope.row)"></span>
          <span v-else>{{ scope.row[item.prop] }}</span>
        </template>
      </template>
    </el-table-column>

    <template v-if="$slots.footer">
      <slot name="footer"></slot>
    </template>
  </el-table>
</template>

<style scoped lang="scss">
$scrollLineHeight: 0.8rem;

.el-table {
  &-scrollbar {
    :deep(.el-table__body-wrapper) {
      overflow: unset;
    }

    :deep(.el-scrollbar) {
      overflow: unset;
    }

    :deep(.el-table__body-wrapper) {
      padding-bottom: $scrollLineHeight;
    }

    :deep(.el-scrollbar__bar) {
      bottom: -(($scrollLineHeight) - $scrollLineHeight * 0.2);
    }
  }
}

.required {
  &::after {
    content: '*';
    color: red;
    margin-left: 4px;
  }
}

:deep(.error-box-shadow) {
  .el-input__wrapper {
    box-shadow: 0 0 0 0.0625rem #ff0000 inset;
  }
}
</style>
